Subclassing API for mIRC (Final Version)
Written by NaquadaBomb @ mirc-dll.com
Ever write a DLL with subclassing and have the problem of your DLL crashing
mIRC?
I have written this DLL package to assist mIRC DLL developers with using
subclassing. One of the most useful abilities to have (when writing
DLL's) is the ability
to subclass a window's proc. The problem is Microsoft has really done
a half ass job of implementing subclassing. This API addresses the
problems people experience when subclassing. It provides a simple way
for many DLL files to subclass the same windows in a harmonious way.
Here's how the whole thing works... I have written a DLL called SubclassMonitor.dll. This DLL needs to reside in the mIRC directory. The purpose of this DLL is to track multiple subclassings of the same window. And to disable all subclassing when processing the WM_CLOSE message. The DLL also sends two message to mIRC's WndProc, SCWM_PRECLOSE and SCWM_CLOSECANCEL, you can use these events for undoing/redoing hooks if you are using them.
When any
DLL that uses the Subclassing API is loaded, it makes a call to initialize the SubclassMonitor.dll if it isn't already initialized. SubclassMonitor.dll
is loaded in to mIRC using LoadLibrary() rather than using mIRC to load the
DLL. The reason SubclassMonitor.dll needs to load this way is because of a bug
in mIRC versions <= 6.17 (which happens to be the current release, atm). I have talked with
Khaled (mIRC's author) about this bug, and it should be fixed in 6.18 when
released, click here for more details.
Please help me push DLL developers in making this a standard in the "mIRC DLL
writing" community.
Here is a brief description of the functions you will need to use in your DLL. Please see the "Example DLL" project source for details.
The first thing to do is include "MonitorAccess.h" and add the MonitorAccess.lib to your project. Then in your DLL's LoadDLL() function, call InjectMonitor(hInstance). After that you simply use SafeSubclassWindow(), UnSubclassWindow(), NextWndProc(), and EnumSubclassing() as needed. Here are the function definitions...
HINSTANCE InjectMonitor(HINSTANCE hInst, HWND hApp, LPSTR
mData);
BOOL SafeSubclassWindow(HINSTANCE hInst, HWND hwnd, WNDPROC lpfn);
BOOL UnSubclassWindow(HINSTANCE hInst, HWND hwnd);
LRESULT NextWndProc(HINSTANCE hInst, HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
INT EnumSubclassing(HINSTANCE hInstDLL, HWND hwnd, ENUMSC enumfunc, LPARAM lParam);
Here's some additional source to get you started...
// HOW TO GET THE DLL's hInstance....
HINSTANCE hInstance = NULL;
extern "C" int WINAPI _DllMainCRTStartup(HANDLE hInstDLL, DWORD, void*)
{
hInstance = (HINSTANCE)hInstDLL;
return 1;
}
// The bare minimum of a subclassed WNDPROC
LRESULT CALLBACK MyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_DESTROY:
UnSubclassWindow(hInstance, hwnd);
PostMessage(hwnd, uMsg, wParam, lParam);
return 0L;
default:
break;
}
return NextWndProc(hInstance, hwnd, uMsg, wParam, lParam);
}